/*
 * Ethan Levine
 * 
 * The contents of this file are subject to the GNU General Public
 * License (GPL) v2.  The full contents of this license can be
 * found at Mathma's website, http://www.codeplex.com/mathma/license
 */

package mathma.core.real.form;

import mathma.core.expr.Variable;
import mathma.core.expr.Expression;
import mathma.core.real.FiniteReal;
import mathma.core.real.Real;

import mathma.core.form.BinaryExpression;
import mathma.core.form.UnknownSuspensionException;

/**
 *
 * @author Ethan Levine
 */
public class PowerExpression extends BinaryExpression<Real, Real> {

    public PowerExpression(Expression<Real> base, Expression<Real> exponent) {
        super(Real.Type, base, exponent);
    }
    
    @Override
    public Real evaluate() {
        return getFirstOperand().evaluate().power(getSecondOperand().evaluate());
    }
    
    @Override
    public Expression<Real> differentiate(Variable<Real> var)
            throws UnknownSuspensionException {
        // The power rule doesn't quite work here, since the exponent may not be constant
        // Instead, I'll use the generalized power rule
        // (f^g)' = (f^g)(g'ln(f)+gf'/f)
        return new MultiplicationExpression(this, new AdditionExpression(
                new MultiplicationExpression(getSecondOperand().differentiate(var),
                new NaturalLogarithmExpression(getFirstOperand())),
                new DivisionExpression(new MultiplicationExpression(
                getSecondOperand(), getFirstOperand().differentiate(var)),
                getFirstOperand())));
    }
    
    @Override
    public PowerExpression newBinaryExpression(Expression<Real> firstExpr, Expression<Real> secondExpr) {
        return new PowerExpression(firstExpr, secondExpr);
    }
}
